(* Copyright (C) 2010 School of Software Engineering, 
 * University of Science and Technology of China.
 *
 * This code is released under a BSD-style license.
 * See the file LICENSE for details.
 *)

functor ByteCode (S: BYTE_CODE_STRUCTS): BYTE_CODE = 
struct 

open S

structure Command =
struct

datatype t
  = Pop
  | Add
  | Sub 
  | Swap 
  | Push of int
  | Jump of int 
  | Jeq of int 
  | Jlt of int
  | Load of int
  | Store of int
  | Stop

val imm = Int.toString

val toString =
 fn Pop => "p"
  | Add => "+"
  | Sub => "-"
  | Swap => "s"
  | Push i=> "c" ^ imm i
  | Jump i=> "j" ^ imm i
  | Jeq i=> "=" ^ imm i 
  | Jlt i=> "<" ^ imm i 
  | Load i=> "r" ^ imm i
  | Store i=> "w" ^ imm i
  | Stop => "." 
  
val toString2 =
 fn Pop => "pop"
  | Add => "add"
  | Sub => "sub"
  | Swap => "swap"
  | Push i=> "push " ^ imm i
  | Jump i=> "jump to " ^ imm i
  | Jeq i=> "if = then jump to " ^ imm i 
  | Jlt i=> "if < then jump to " ^ imm i 
  | Load i=> "load from " ^ imm i
  | Store i=> "store to " ^ imm i
  | Stop => "stop" 

val layout = Layout.str o toString
val layout2 = Layout.str o toString2

val max = ref 0
val rec findMax =
 fn [] => ()
  | x::xs =>
    let val n = String.size x
        val _ = if n>(!max)
                then max := n
                else ()
    in  findMax xs
    end

val rec spaces =
 fn 0 => ""
  | n => String.concat [" ", spaces (n-1)]

fun layouts cs =
    let val css = List.map toString cs
        val _ = findMax css
        val newCss = List.map 
                         (fn x =>
                         String.concat [x, spaces (!max - String.size x+1)])
                         css 
        val newLay = List.map Layout.str newCss
    in  (Layout.seq newLay, !max+1)
    end

end

structure CodeHeap =
struct

datatype t = T of Command.t list

val layout =
 fn T cs => Layout.align (List.map Command.layout cs)
end

end
